package mapservice;

import geometry.ILocation;
import geometry.IPlace;
import geometry.IRoute;
import geometry.entity.GeometryFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import net.sf.json.JSONObject;

public class DirectionsServiceJSON {

    // URL prefix to the geocoder
    private static final String DIRECTION_REQUEST_PREFIX_FOR_JSON = "http://maps.google.com/maps/api/directions/json";
    private IRoute route;

    public DirectionsServiceJSON() {
        route = GeometryFactory.getRouteInstance();
    }

    /**
     * Get the value of route
     *
     * @return the value of route
     */
    public IRoute getRoute() {
        return route;
    }

    /**
     * Set the value of route
     *
     * @param route new value of route
     */
    public void setRoute(IRoute route) {
        this.route = route;
    }

    public JSONObject getDirectionRoute(ILocation Origin, ILocation Destination) throws IOException {
        route.setOrigin((IPlace) Origin);
        route.setDestination((IPlace) Destination);
        return getDirectionRoute(LocationToString(Origin), LocationToString(Destination));
    }

    public JSONObject getDirectionRoute(IPlace Origin, IPlace Destination) throws IOException {
        String origin = Origin.toString();
        String destination = Destination.toString();
        route.setOrigin(Origin);
        route.setDestination(Destination);
        return getDirectionRoute(origin, destination);

    }

    public JSONObject getDirectionRoute(String origin, String destination) throws IOException {
        JSONObject json = new JSONObject();
        JSONObject destinationLocation = new JSONObject();
        destinationLocation.accumulate("destination", destination);
        String option = "?origin=" + URLEncoder.encode(origin, "UTF-8") + "&destination=" + URLEncoder.encode(destination, "UTF-8")+"&region=cn";
        URL url = new URL(DIRECTION_REQUEST_PREFIX_FOR_JSON + option + "&sensor=false");

        System.out.println(url);
        // prepare an HTTP connection to the geocoder
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        try {
            // open the connection and get results as InputSource.
            conn.connect();

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    conn.getInputStream(),"UTF-8"));
            String lines;
            StringBuilder sb = new StringBuilder("");
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes(),"UTF-8");
                sb.append(lines);
            }

            JSONObject rootJSON = JSONObject.fromObject(sb.toString());
            JSONObject routeJSON;
            JSONObject legsJSON;
            JSONObject stepsJSON;
            JSONObject distanceJSON = new JSONObject();
            int distance = 0;

            for (Object obj : rootJSON.getJSONArray("routes")) {
                routeJSON = JSONObject.fromObject(obj);
                for (Object obj2 : routeJSON.getJSONArray("legs")) {
                    legsJSON = JSONObject.fromObject(obj2);
                    for (Object obj3 : legsJSON.getJSONArray("steps")) {
                        stepsJSON = JSONObject.fromObject(obj3);
                        distanceJSON = stepsJSON.getJSONObject("distance");
                        distance += distanceJSON.getInt("value");
                        stepsJSON.remove("duration");
                        stepsJSON.remove("html_instructions");
                        stepsJSON.remove("polyline");
                        stepsJSON.remove("distance");
                        stepsJSON.remove("travel_mode");
                        json.accumulate("route", stepsJSON);

                    }
                }
            }
            json.accumulate("distance", distance);
        } finally {
            conn.disconnect();
        }

        return json;

    }

    private String LocationToString(ILocation location) {
        return location.getLat() + "," + location.getLng();
    }



    public static void main(String[] argv) throws IOException {
        float Lat = 26.051567f;
        float Lng = 119.345316f;
        DirectionsServiceJSON ds = new DirectionsServiceJSON();
        System.out.println(ds.getDirectionRoute(Lat + "," + Lng, "26.054515838623047,119.34273529052734"));
    }
}
